﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace StructuredClient
{
    public class VolanoClient
    {
     
        public delegate void ChannelJoiningInformation(object sender, VolanoMyJoiningInformationMessage Details);

        
        public event EventHandler IncomingPrivateChannelRequest;

        public event ChannelJoiningInformation JoiningChannelFailed;

        public event ChannelJoiningInformation JoiningChannelSucceeded;

        /// <summary>
        /// Returns a list of channels which were joined by the user.
        /// </summary>
        public StructuredClient.VolanoPublicChannel[] JoinedChannels
        {
            get
            {
                throw new System.NotImplementedException();
            }
            set
            {
            }
        }

        public StructuredClient.VolanoPrivateChannel[] PrivateChannels
        {
            get
            {
                throw new System.NotImplementedException();
            }
            set
            {
            }
        }

        public IVolanoFactory FactoryClass
        {
            get
            {
                throw new System.NotImplementedException();
            }
            set
            {
            }
        }
        /// <summary>
        /// Returns a list of available channels provided by this client.
        /// </summary>
        public StructuredClient.VolanoChannelInfo[] GetPublicChannels()
        {
            throw new System.NotImplementedException();
        }

        internal void SetIncomingMessage(IVolanoFactory sender, VolanoMessageBase Message)
        {

            // Check if the message shall be delivered to a specific channel
            if (Message.DeliverToChannel == true)
            {

                // Yes, message shall be delivered to a specific channel.
                // Check if the use has joined the channel. Try to deliver the message.

                VolanoChannelBase VC = this.GetJoinedChannelByName(Message.ChannelName);
                if (VC == null)
                {

                    // Problem: The channel which should get the message is not joined
                    String ExMsg = string.Format("Got message for room {0}. You're not a member of this room.", Message.ChannelName);
                    throw new ApplicationException(ExMsg);

                }
                else
                {

                    // Use case: deliver the message to the joined channel
                    VC.SetIncomingMessage(this, Message);
                }


            } else {

                // No, the message shall NOT be delivered to a specific channel.
                // That means that this message is a information for this, the ClientClass.
                // Check the type of the incomming message and handle it.



                //TODO: Implement the different actions if the VolanoClient-Class gets a message which shall NOT be delivered to a joined channel.

                // Message informs about the status of the joining process.
                if (typeof(VolanoMyJoiningInformationMessage ) == Message.GetType()) 
                {
                    VolanoMyJoiningInformationMessage M = (VolanoMyJoiningInformationMessage)Message;
                    if (M.State == eJoiningStatus.Success)
                    {
                        this.JoiningChannelSucceeded(this, M);
                    } else {
                        this.JoiningChannelFailed(this, M);
                    }

                            
                }
            }

              


            throw new System.NotImplementedException();
        }

        public VolanoChannelInfo GetChannelByName(string ChannelName)
        {
            throw new System.NotImplementedException();
        }

        /// <summary>
        /// Returns the joined channel with the given name.
        /// This method searchs in the private joined and in the public joined channels.
        /// If no channel with the given name is joined this method returns null.
        /// </summary>
        /// <param name="ChannelName">Name of the channel (ChannelIdentifier)</param>
        /// <returns></returns>
        public VolanoChannelBase GetJoinedChannelByName(string ChannelName)
        {

            // Find the given name in the joined public channels
            foreach (VolanoPublicChannel C in this.JoinedChannels)
            {
                if (C.ChannelIdentifier.Equals(ChannelName)) return C;
            }


            // Find the given name in the joined private channels
            foreach (VolanoPrivateChannel C in this.PrivateChannels)
            {
                if (C.ChannelIdentifier.Equals(ChannelName)) return C;
            }

            // No channel with the given name was found. Return null.
            return null;
        }

        public void JoinChannel(VolanoChannelInfo Channel)
        {
            throw new System.NotImplementedException();
        }
    }
}
